import Plugin from '../../lib/plugins/plugin.js'
import Bott from "./lib/Bott.js"
import yaml from "yaml"
import fs from "node:fs"
import path from "node:path"

export class QQGuild extends Plugin {
    #cfgPak = "./plugins/QQGuild-Plugin/package.json"
    #cfgDir = "./plugins/QQGuild-Plugin/config"
    #cfgTpl = yaml.parse(fs.readFileSync(path.join(this.#cfgDir, ".template.yaml"), "UTF-8"))

    constructor() {
        super({
            name: "QQ频道插件",
            priority: -10000,
            rule: [{ reg: "^#频道插件\\.", fnc: "控制台", permission: "master" }]
        })
    }

    init() {
        if (global.__QQGuild__ === true) {
            logger.warn("[QQ频道插件] 警告！警告！警告！出现未知错误！")
            return
        }

        let { name, version, author } = JSON.parse(fs.readFileSync(this.#cfgPak))
        logger.info(`欢迎使用QQ频道插件(${name}).v${version} 编写者：${author}`)

        global.Bott = new Map()
        global.__QQGuild__ = true

        let cfgReg = /^\d+\.yaml$/
        let fes = fs.readdirSync(this.#cfgDir).filter(x => cfgReg.test(x))
        logger.info("[QQ频道插件] 发现机器人配置", fes.length, "个")

        for (let cfg of fes) {
            let cfgP = path.join(this.#cfgDir, cfg)
            let cfgY = fs.readFileSync(cfgP, "UTF-8")
            let cfgJ = { file: cfgP, ...yaml.parse(cfgY) }
            this.initBott(cfgJ)
        }

        this.initHooks()
    }

    async initHooks() {
        let getGroupMemberInfo = Bot.getGroupMemberInfo
        Bot.getGroupMemberInfo = async (...args) => {
            return await getGroupMemberInfo(...args).catch(() => {
                return {
                    group_id: 0,
                    user_id: 0,
                    nickname: "",
                    card: "",
                    sex: "",
                    age: 0,
                    area: "",
                    join_time: 0,
                    last_sent_time: 0,
                    level: 0,
                    rank: "",
                    role: "",
                    title: "",
                    title_expire_time: 0,
                    shutup_time: 0,
                    update_time: 0
                }
            })
        }
    }

    initBott(config) {
        global.Bott.set(global.Bott.size + 1, new Bott(config))
    }

    addBott(config) {
        let cfg = { ...this.#cfgTpl }
        cfg.botConfig.appId = config[0]
        cfg.botConfig.token = config[1]
        cfg.botConfig.sandbox = config[2] === "true"
        cfg.botConfig.allMsg = config[3] === "true"
        cfg.autoStart = config[4] === "true"
        let p = path.join(this.#cfgDir, `${cfg.botConfig.appId}.yaml`)
        fs.writeFileSync(p, yaml.stringify(cfg), "UTF-8")
        cfg.file = p
        this.initBott(cfg)
    }

    delBott(index) {
        let bott = global.Bott.get(index)
        if (bott) {
            bott.stop()
            fs.rmSync(bott.configFile)
            global.Bott.delete(index)
        }
    }

    startBott(index, isAll) {
        if (isAll) {
            global.Bott.forEach(bott => bott.start())
        } else {
            global.Bott.get(index)?.start()
        }
    }

    stopBott(index, isAll) {
        if (isAll) {
            global.Bott.forEach(bott => bott.stop())
        } else {
            global.Bott.get(index)?.stop()
        }
    }

    async reStartBott(index, isAll) {
        this.stopBott(index, isAll)
        await new Promise(r => setTimeout(r, 3000))
        this.startBott(index, isAll)
    }

    getBottState(index) {
        let bott = global.Bott.get(index)
        if (!bott) return "标号无效！"
        return "#频道插件.机器人.状态\n"
            + `- 标号 => ${index}\n`
            + `：${bott.botName}\n`
            + `：${bott.botState}`
    }

    getBottStateList() {
        let text = "#频道插件.机器人.列表"
        if (global.Bott.size < 1) return text + "\n- 无"
        global.Bott.forEach((bott, index) => {
            text += `\n- 标号 => ${index}\n`
                + `：${bott.botName}\n`
                + `：${bott.botState}`
        })
        return text
    }

    setBott(index, cmd, args) {
        let bott = global.Bott.get(index)
        if (!bott) return "标号无效！"

        let save = () => {
            fs.writeFileSync(bott.configFile, yaml.stringify(bott), "UTF-8")
        }

        switch (cmd) {
            case "查看":
                return "#频道插件.机器人.设置 查看\n"
                    + `- APPID：${bott.botConfig.appId}\n`
                    + `- TOKEN：${bott.botConfig.token}\n`
                    + `- 沙盒测试：${bott.botConfig.sandbox ? "已开启" : "已关闭"}\n`
                    + `- 全部消息：${bott.botConfig.allMsg ? "已开启" : "已关闭"}\n`
                    + `- 直接启动：${bott.autoStart ? "已开启" : "已关闭"}`
            case "直接启动":
                switch (args[0]) {
                    case "开启":
                        bott.autoStart = true
                        break
                    case "关闭":
                        bott.autoStart = false
                        break
                    default:
                        return "开启/关闭？"
                }
                save()
                return "已设置. 重启生效."
            case "沙盒测试":
                switch (args[0]) {
                    case "开启":
                        bott.botConfig.sandbox = true
                        break
                    case "关闭":
                        bott.botConfig.sandbox = false
                        break
                    default:
                        return "开启/关闭？"
                }
                save()
                return "已设置. 重连生效."
            case "全部消息":
                switch (args[0]) {
                    case "开启":
                        bott.botConfig.allMsg = true
                        break
                    case "关闭":
                        bott.botConfig.allMsg = false
                        break
                    default:
                        return "开启/关闭？"
                }
                save()
                return "已设置. 重连生效.\n注意！！公域机器人必须设置为关闭."
            case "命令过滤.查看":
                let text = "#频道插件.机器人.设置 命令过滤.查看"
                if (bott.cmdConfig.cMsg) {
                    text += `\n- ${bott.cmdConfig.cMsg}`
                } else {
                    text += `\n- 无`
                }
                if (bott.cmdConfig.cList.size > 0) {
                    bott.cmdConfig.cList.forEach(x => text += `\n： ${x}`)
                } else {
                    text += "\n： 无"
                }
                return text
            case "命令过滤.消息":
                if (args.length < 1) return "啥消息？"
                if (args[0] === "空") {
                    bott.cmdConfig.cMsg = null
                } else {
                    bott.cmdConfig.cMsg = args.join("\n")
                }
                save()
                break
            case "命令过滤.添加":
                if (args.length < 1) return "添加啥？"
                args.forEach(x => bott.cmdConfig.cList.add(x))
                save()
                return "已添加."
            case "命令过滤.删除":
                if (args.length < 1) return "删除啥？"
                if (args[0] === "全部") {
                    bott.cmdConfig.cList.clear()
                } else {
                    args.forEach(x => bott.cmdConfig.cList.delete(x))
                }
                save()
                return "已删除."
            default:
                return "暂不支持此设置."
        }

        return "已设置."
    }

    async 控制台(e) {
        if (global.__QQGuild__ !== true) {
            logger.warn("[QQ频道插件] 警告！警告！警告！出现未知错误！")
            return
        }

        if (e.message_type !== "private" || e.sub_type !== "friend") return

        let cmd = e.msg
            .replace(/\s+/g, " ")
            .trim()
            .split(" ")

        switch (cmd.shift()) {
            case "#频道插件.机器人.添加":
                this.addBott(cmd)
                e.reply("已添加.")
                break
            case "#频道插件.机器人.删除":
                this.delBott(parseInt(cmd[0]))
                e.reply("已删除.")
                break
            case "#频道插件.机器人.启动":
                this.startBott(parseInt(cmd[0]), cmd[0] === "全部")
                e.reply("正在启动...")
                break
            case "#频道插件.机器人.停止":
                this.stopBott(parseInt(cmd[0]), cmd[0] === "全部")
                e.reply("正在停止...")
                break
            case "#频道插件.机器人.重连":
                this.reStartBott(parseInt(cmd[0]), cmd[0] === "全部")
                e.reply("正在重连...")
                break
            case "#频道插件.机器人.状态":
                e.reply(this.getBottState(parseInt(cmd[0])))
                break
            case "#频道插件.机器人.列表":
                e.reply(this.getBottStateList())
                break
            case "#频道插件.机器人.设置":
                e.reply(this.setBott(parseInt(cmd.shift()), cmd.shift(), cmd))
                break
            default:
                e.reply("暂不支持此命令.")
        }
    }
}
